/*
 * 
 *  This file is part of Sourceprojects.org Thracia.
 *  Copyright 2010 noctarius
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * 
 */
package org.sourceprojects.thracia;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.InvalidPropertiesFormatException;
import java.util.Properties;
import java.util.logging.Logger;

import org.sourceprojects.thracia.interfaces.VersionRetriever;

/**
 * @author noctarius
 * 
 */
public class ReporterConfig implements VersionRetriever {
	private final VersionRetriever versionretriever;
	private final Class<?> mainclass;

	private boolean showStacktrace = true;
	private boolean autosend = true;
	private String address = "localhost";
	private int port = 80;
	private long delay = 60000;
	private String reportdir = "./logs/report";
	private Class<?> logger = Logger.class;
	private String outputwriter = "org.sourceprojects.thracia.output.writer.XsqlWriter";

	/**
	 * Initializes a new ReportConfig class with standard values
	 * 
	 * @param versionretriever
	 */
	public ReporterConfig(VersionRetriever versionretriever, Class<?> main) {
		this.versionretriever = versionretriever;
		mainclass = main;
	}

	/**
	 * Initializes a new ReportConfig class from a properties file<br>
	 * in filesystem specified in file
	 * 
	 * @param versionretriever
	 * @param file
	 */
	public ReporterConfig(VersionRetriever versionretriever, Class<?> main,
			File file) {
		this.versionretriever = versionretriever;
		mainclass = main;

		Properties prop = null;
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(file);

			prop = new Properties();
			prop.loadFromXML(fis);
		} catch (final FileNotFoundException e) {
			e.printStackTrace();
		} catch (final InvalidPropertiesFormatException e) {
			e.printStackTrace();
		} catch (final IOException e) {
			e.printStackTrace();
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (final IOException e) {
					e.printStackTrace();
				}
			}
		}

		if (prop == null) {
			return;
		}

		readConfig(prop);
	}

	/**
	 * Initializes a new ReportConfig class from a properties file<br>
	 * through a classloader from packagetree specified in file<br>
	 * Example: "org/sourceprojects/reporter/config.xml"
	 * 
	 * @param versionretriever
	 * @param file
	 */
	public ReporterConfig(VersionRetriever versionretriever, Class<?> main,
			String file) {
		this.versionretriever = versionretriever;
		mainclass = main;

		Properties prop = null;
		InputStream is = null;
		try {
			final ClassLoader cl = this.getClass().getClassLoader();
			is = cl.getResourceAsStream(file);

			if (is == null) {
				return;
			}

			prop = new Properties();
			prop.loadFromXML(is);
		} catch (final InvalidPropertiesFormatException e) {
			e.printStackTrace();
		} catch (final IOException e) {
			e.printStackTrace();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (final IOException e) {
					e.printStackTrace();
				}
			}
		}

		if (prop == null) {
			return;
		}

		readConfig(prop);
	}

	public final String getAddress() {
		return address;
	}

	public final long getDelay() {
		return delay;
	}

	public final Class<?> getLogger() {
		return logger;
	}

	public final Class<?> getMainclass() {
		return mainclass;
	}

	public String getOutputwriter() {
		return outputwriter;
	}

	public final int getPort() {
		return port;
	}

	public final String getReportdir() {
		return reportdir;
	}

	public final VersionRetriever getVersionretriever() {
		return versionretriever;
	}

	public final boolean isAutosend() {
		return autosend;
	}

	private void readConfig(Properties prop) {
		for (final Object t : prop.keySet()) {
			final String key = (String) t;

			if (key.equals("address")) {
				setAddress(prop.getProperty(key));
			} else if (key.equals("showstacktrace")) {
				final boolean autosend = Boolean.parseBoolean(prop
						.getProperty(key));
				setAutosend(autosend);
			} else if (key.equals("autosend")) {
				final boolean autosend = Boolean.parseBoolean(prop
						.getProperty(key));
				setAutosend(autosend);
			} else if (key.equals("delay")) {
				try {
					final long delay = Long.parseLong(prop.getProperty(key));
					setDelay(delay);
				} catch (final NumberFormatException e) {
					e.printStackTrace();
				}
			} else if (key.equals("logger")) {
				try {
					final Class<?> logger = Class
							.forName(prop.getProperty(key));

					if (logger != null) {
						setLogger(logger);
					}
				} catch (final ClassNotFoundException e) {
					e.printStackTrace();
				}
			} else if (key.equals("outputwriter")) {
				setOutputwriter(prop.getProperty(key));
			} else if (key.equals("port")) {
				try {
					final int port = Integer.parseInt(prop.getProperty(key));
					setPort(port);
				} catch (final NumberFormatException e) {
					e.printStackTrace();
				}
			} else if (key.equals("reportdir")) {
				setReportdir(prop.getProperty(key));
			}
		}
	}

	public final void setAddress(String address) {
		this.address = address;
	}

	public final void setAutosend(boolean autosend) {
		this.autosend = autosend;
	}

	public final void setDelay(long delay) {
		this.delay = delay;
	}

	public final void setLogger(Class<?> logger) {
		this.logger = logger;
	}

	public void setOutputwriter(String outputwriter) {
		this.outputwriter = outputwriter;
	}

	public final void setPort(int port) {
		this.port = port;
	}

	public final void setReportdir(String reportdir) {
		this.reportdir = reportdir;
	}

	public final boolean isShowStacktrace() {
		return showStacktrace;
	}

	public final void setShowStacktrace(boolean showStacktrace) {
		this.showStacktrace = showStacktrace;
	}

	public String getProductName() {
		return "zpAdmin2";
	}

	public String getVersionNumber() {
		return "0.1.2";
	}
}
